import { CacheService } from '@app/cache';
import { ConfigureService } from '@app/configure';
import { Device } from '@app/db/entities/Device';
import { PrivateChargeRecord } from '@app/db/entities/PrivateChargeRecord';
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { AliIotService } from 'apps/ali-iot/src/ali-iot.service';
import { Repository } from 'typeorm';

@Injectable()
export class PrivateChargeService {
    private PstartChargeResKey:string
    private PendChargeResKey:string
    private PdeviceChargingOrderKey:string

    private deviceIdPortToOrderIdReg:string //设备id和端口号对应的订单id

    constructor(
        @InjectRepository(PrivateChargeRecord) protected privateChargeRecord:Repository<PrivateChargeRecord>,
        @InjectRepository(Device) protected device:Repository<Device>,
        private readonly cache:CacheService,
        private readonly config:ConfigureService,
        private readonly aliIot:AliIotService,
    ){
        this.PstartChargeResKey = config.get('PstartChargeResKey')
        this.PendChargeResKey = config.get('PendChargeResKey')
        this.PdeviceChargingOrderKey = config.get('PdeviceChargingOrderKey')

        this.deviceIdPortToOrderIdReg = config.get('deviceIdPortToOrderIdReg')
    }

    async startCharge(msg) {
        const id = Number(msg.order.slice(0, -1))
        const deviceId = Number(msg.id)
        const port = msg.port
        const status = msg.s
        const err = msg.errCode
        const record = await this.privateChargeRecord.findOne({
          where : {id : id},
          select : ['status']
        })
    
    
        if(!record || record.status != 0) return
    
        let f = 'y'
    
        if(status == 0) { //失败
            f = 'n'
            this.privateChargeRecord.update({id : id}, {status : 3, errorCode : err})
        }else { //成功
          this.privateChargeRecord.update({id : id}, {status : 1})
          this.cache.client.sadd(this.PdeviceChargingOrderKey + deviceId, id)
          this.cache.set(this.deviceIdPortToOrderIdReg.replace(/\?/, String(deviceId)).replace(/\?/, String(port)), msg.order)
        }
    
        this.cache.set(this.PstartChargeResKey + id, f, 20)
        
    }

    //手动停止私人充电
    async stopCharge(msg) {
        const id = Number(msg.order.slice(0, -1))
        let f = 'y'

        if(msg.s == 0) { //失败
            f = 'n'
        }else { //成功
            
            this.finish(id, msg.chargeTime, msg.chargequantity, msg.maxPower, 12)

            //把端口状态改成空闲
            //console.log('把端口状态改成空闲')
            this.device.update({id : Number(msg.id)}, {
                portStatus : () => {
                return `JSON_SET(port_status, "$[${msg.port - 1}]", 0)`
                }
            })
        }

        this.cache.set(this.PendChargeResKey + id, f, 20)
    }

    //设备结束的
    async endCharge(topic:string, msg) {
        const topics = topic.split('/')

        const message:any = {type : 14, s : 1, port : msg.port}
        if('cardID' in msg) {
            message.cardID = msg.cardID
        }

        this.aliIot.pubToDevice(msg.id, topics[1], message)


        if(msg.cardID) { //卡充电的

        }else {
            this.finish(Number(msg.order.slice(0, -1)), msg.chargeTime, msg.chargequantity, msg.maxPower, msg.y)

            //把端口状态改成空闲
            //console.log('把端口状态改成空闲')
            this.device.update({id : Number(msg.id)}, {
                portStatus : () => {
                return `JSON_SET(port_status, "$[${msg.port - 1}]", 0)`
                }
            })
        }

    }



    async finish(id:number, chargeTime:number, kwh:number, maxPower:number, reason:number) {
        const record = await this.privateChargeRecord.findOne({
            where : {id : id},
        })
    
        if(!record || record.status != 1) return

        this.cache.del(this.deviceIdPortToOrderIdReg.replace(/\?/, String(record.deviceId)).replace(/\?/, String(record.port)))

        await this.privateChargeRecord.update({id : id}, {
            stopReason : reason,
            status : 2,
            endTime : Math.floor(Date.now() / 1000),
            consumeKwh : kwh,
            chargeData : {time : chargeTime, maxPower : maxPower}
        })

          //从充电中订单中移除
        this.cache.client.srem(this.PdeviceChargingOrderKey + record.deviceId, id)
    }
}
